<?php
declare(strict_types=1);
namespace Aincrid\MySwoole;

use Aincrid\MySwoole\Facade\Config;
use Aincrid\MySwoole\Log\Channel\iLogChannel;
use Aincrid\MySwoole\Log\Driver\iLogDriver;

class Log
{
    const DEBUG_LEVEL = 0;
    const INFO_LEVEL = 1;
    const WARNING_LEVEL = 2;
    const ERROR_LEVEL = 3;
    const FATAL_ERROR = 4;

    protected string $logRootDir;

    protected string $defaultConfigChannel;
    protected iLogChannel $channel;

    protected iLogDriver $driver;

    protected array $logConfigs;

    public function __construct()
    {
        $this->logConfigs = Config::get('log');
        $this->logRootDir = $this->logConfigs['log_root'];
        $this->defaultConfigChannel = $this->logConfigs['default'];

        $this->initChannel();
        $this->initDriver();
    }

    protected function initChannel()
    {
        $channelConfigs = $this->logConfigs['channels'][$this->defaultConfigChannel];
        $channelClass = ucfirst($channelConfigs['channel']) . 'Channel';
        $this->channel = new ('\Aincrid\MySwoole\Log\Channel\\' . $channelClass)();

    }

    protected function initDriver()
    {
        $channelConfigs = $this->logConfigs['channels'][$this->defaultConfigChannel];
        $driverClass = ucfirst($channelConfigs['driver']) . 'Driver';
        $this->driver = new ('\Aincrid\MySwoole\Log\Driver\\' . $driverClass)();
    }


    protected function log(string $log, int $logLevel): int|bool
    {
        $fileInfo = $this->channel->getLogFile($this->logRootDir);
        $logLevel = match ($logLevel) {
            0 => 'debug',
            1 => 'info',
            2 => 'warn',
            3 => 'error',
            4 => 'fatal'
        };
        return $this->driver->write($fileInfo, $log, $logLevel);
    }


    /**
     * @param string $log
     * @return mixed
     */
    public function debug(string $log): int|bool
    {
        return $this->log($log, 0);
    }

    /**
     *
     * @param string $log
     * @return mixed
     */
    public function info(string $log): int|bool
    {
        return $this->log($log, 1);
    }

    /**
     *
     * @param string $log
     * @return mixed
     */
    public function warn(string $log): int|bool
    {
        return $this->log($log, 2);
    }

    /**
     *
     * @param string $log
     * @return mixed
     */
    public function error(string $log): int|bool
    {
        return $this->log($log, 3);
    }

    /**
     *
     * @param string $log
     * @return mixed
     */
    public function fatal(string $log): int|bool
    {
        return $this->log($log, 4);
    }


}